package org.ece3574.virga;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnAreaTouchListener;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.Scene.ITouchArea;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;

import android.hardware.SensorManager;
import android.widget.Toast;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;

/**
 * Referenced code by Nicolas Gramlich
 */
public class CharJumpActivity extends BaseExample implements IAccelerometerListener, IOnSceneTouchListener, IOnAreaTouchListener {
 

        private static final int CAMERA_WIDTH = 360;
        private static final int CAMERA_HEIGHT = 240;
        private Body body;
        private AnimatedSprite face;



        private BitmapTextureAtlas mBitmapTextureAtlas;

        private TiledTextureRegion mBoxFaceTextureRegion;
        private TiledTextureRegion mCircleFaceTextureRegion;

        private PhysicsWorld mPhysicsWorld;

        private float mGravityX;
        private float mGravityY;
        private Scene mScene;


        @Override
        public Engine onLoadEngine() {
                Toast.makeText(this, "Touch the screen to make the man jump.", Toast.LENGTH_LONG).show();
                final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
                final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
                engineOptions.getTouchOptions().setRunOnUpdateThread(true);
                return new Engine(engineOptions);
        }

        @Override
        public void onLoadResources() {
                this.mBitmapTextureAtlas = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
                BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
                this.mBoxFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "dude.png", 0, 0, 2, 1); // 64x32
                this.mCircleFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "dude.png", 0, 32, 2, 1); // 64x32
                this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
        }

        @Override
        public Scene onLoadScene() {
                this.mEngine.registerUpdateHandler(new FPSLogger());

                this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);

                this.mScene = new Scene();
                this.mScene.setBackground(new ColorBackground(51, 102, 255));
                this.mScene.setOnSceneTouchListener(this);

                final Shape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2);
                final Shape roof = new Rectangle(0, 0, CAMERA_WIDTH, 2);
                final Shape left = new Rectangle(0, 0, 2, CAMERA_HEIGHT);
                final Shape right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT);

                final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
                PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
                PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
                PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
                PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);

                this.mScene.attachChild(ground);
                this.mScene.attachChild(roof);
                this.mScene.attachChild(left);
                this.mScene.attachChild(right);

                this.mScene.registerUpdateHandler(this.mPhysicsWorld);

                this.mScene.setOnAreaTouchListener(this);
                
                final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
                face = new AnimatedSprite(CAMERA_WIDTH/2, 0, this.mBoxFaceTextureRegion);;
                body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
                
                this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));

                face.animate(new long[]{200,200}, 0, 1, true);
                face.setUserData(body);
                this.mScene.registerTouchArea(face);
                this.mScene.attachChild(face);

                return this.mScene;
        }

        @Override
        public boolean onAreaTouched( final TouchEvent pSceneTouchEvent, final ITouchArea pTouchArea,final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
        	return true;
        }

        @Override
        public void onLoadComplete() {

        }

        public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
            if(pSceneTouchEvent.isActionDown()) {
                //final AnimatedSprite face = (AnimatedSprite) pTouchArea ;
                this.jumpFace(face);
                return true;
        }

        return false;
        }

        @Override
        public void onAccelerometerChanged(final AccelerometerData pAccelerometerData) {
                //this.mGravityX = pAccelerometerData.getX();
                this.mGravityY = pAccelerometerData.getY();

                final Vector2 gravity = Vector2Pool.obtain(0, this.mGravityY);
                this.mPhysicsWorld.setGravity(gravity);
                Vector2Pool.recycle(gravity);
        }

        @Override
        public void onResumeGame() {
                super.onResumeGame();

                this.enableAccelerometerSensor(this);
        }

        @Override
        public void onPauseGame() {
                super.onPauseGame();

                this.disableAccelerometerSensor();
        }

        private void jumpFace(final AnimatedSprite face) {

        	final Body faceBody = (Body)face.getUserData();
            final Vector2 velocity = Vector2Pool.obtain(this.mGravityX/2 * -1, this.mGravityY/2 * -1);
            faceBody.setLinearVelocity(velocity);
            Vector2Pool.recycle(velocity);
        }


}